//*****************************************************************************
//* Foxit Digital Rights Management Library
//*
//* Foxit Software Inc.
//* Copyright(C) 2005-2010, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
//* and trade secrets of Foxit Software Inc.
//*****************************************************************************
/**
 * @addtogroup FDRM
 * @{
 */

/**
 * @file
 * @brief Define interfaces, classes & functions for PKI.
 */

#ifndef _FDRM_PKI
#define _FDRM_PKI

//Classes defined in this header
class IFDRM_CertificateRead;
	class IFDRM_CertificateWrite;

//*****************************************************************************
//* Key creation
//*****************************************************************************
/**
 * @name Create public/private key pair
 * Valid PKI operators are FDRM_OPERATOR_RSA_XXX and FDRM_OPERATOR_DSA_XXX.
 */
/*@{*/

/**
 * @brief	Create a pair of PKI keys.
 * @param[in] op			PKI operator. Valid PKI operators are FDRM_OPERATOR_RSA_XXX and FDRM_OPERATOR_DSA_XXX.
 * @param[out] bcsPublic	stores the public key value.
 * @param[out] bcsPrivate	stores the private key value.
 * @return	A non-negative value means keys are successfully created;
 *			-1 if PKI operator is not permitted;
 *			Return other negative value if any error occurs.
 */
FX_INT32	FDRM_PKI_KeyPair_Create(const CFDRM_Operator &op, CFDRM_ByteCryptoString &bcsPublic, CFDRM_ByteCryptoString &bcsPrivate);

/*@}*/

//*****************************************************************************
//* Signature
//*****************************************************************************
/**
 * @name Create or verify signature
 * Valid PKI operators are FDRM_OPERATOR_RSA_XXX and FDRM_OPERATOR_DSA_XXX.
 */
/*@{*/

/**
 * @brief	Create signature.
 * @param[in] op			PKI operator. Valid PKI operators are FDRM_OPERATOR_RSA_XXX and FDRM_OPERATOR_DSA_XXX.
 * @param[in] bcsKey		signature key, used to encrypt signature data, and should have the same length as key.
 * @param[in] bksSignData	the primitive signature data.
 * @param[out] bksSignValue	stores the signature value.
 * @return	A non-negative value means signature is successfully created;
 *			-1 if PKI operator is not permitted;
 *			-2 if key does not match or is error;
 *			-3 if primitive data is empty or cannot be used;
 *			Return other negative value if any error occurs.
 */
FX_INT32	FDRM_PKI_Signature_Create(const CFDRM_Operator &op, const CFDRM_ByteCryptoString &bcsKey, const CFDRM_ByteKeyString &bksSignData, CFDRM_ByteKeyString &bksSignValue);

/**
 * @brief	Verify signature.
 * @param[in] op			PKI operator. Valid PKI operators are FDRM_OPERATOR_RSA_XXX and FDRM_OPERATOR_DSA_XXX.
 * @param[in] bcsKey		signature key, used to encrypt signature data, and should have the same length as key.
 * @param[in] bksSignData	the primitive signature data.
 * @param[in] bksSignValue	the signature value.
 * @return	> 0 means signature is successfully verified;
 *			0 if signature verification is wrong;
 *			-1 if PKI operator is not permitted;
 *			-2 if key does not match or is error;
 *			-3 if primitive data is empty or cannot be used;
 *			Return other negative value if any error occurs.
 */
FX_INT32	FDRM_PKI_Signature_Verify(const CFDRM_Operator &op, const CFDRM_ByteCryptoString &bcsKey, const CFDRM_ByteKeyString &bksSignData, const CFDRM_ByteKeyString &bksSignValue);

/*@}*/

//*****************************************************************************
//* Certificate
//*****************************************************************************
/**
 * @name Certificate
 */
/*@{*/

class IFDRM_CertificateRead : public CFDRM_Object
{
public:
	virtual IFDRM_DescRead*			GetDescRead() const = 0;
	virtual FX_INT32				VerifyCertificate(const CFDRM_DescData &descData, const CFDRM_ScriptData &scriptData) = 0;

	virtual FX_INT32				GetType(CFX_ByteString &bsType) const = 0;
	virtual FX_INT32				GetVersion(CFX_ByteString &bsVersion) const = 0;
	virtual FX_INT32				GetSerialNumber(CFX_ByteString &bsSN) const = 0;
	virtual FX_INT32				GetEnvironmentInfo(CFX_ByteString &bsInfo) const = 0;
	virtual FX_INT32				GetEnvironmentHashType(CFX_ByteString &bsHashType) const = 0;
	virtual FX_INT32				GetEnvironmentHashValue(CFX_ByteString &bsHashValue) const = 0;
	virtual IFDRM_CategoryRead*		GetCertificateParams() const = 0;

	virtual FX_INT32				GetIssuerID(CFX_ByteString &bsID) const = 0;
	virtual FX_INT32				GetIssuerSerialNumber(CFX_ByteString &bsSN) const = 0;
	virtual FX_INT32				GetIssuerServiceURL(CFX_ByteString &bsURL) const = 0;
	virtual IFDRM_CategoryRead*		GetIssuerParams() const = 0;
	virtual FX_INT32				GetMasterID(CFX_ByteString &bsID) const = 0;
	virtual FX_INT32				GetMasterSerialNumber(CFX_ByteString &bsSN) const = 0;
	virtual FX_INT32				GetMasterServiceURL(CFX_ByteString &bsURL) const = 0;
	virtual IFDRM_CategoryRead*		GetMasterParams() const = 0;

	virtual FX_INT32				GetSubjectID(CFX_ByteString &bsID) const = 0;
	virtual FX_INT32				GetValidity(CFX_ByteString &bsStart, CFX_ByteString &bsEnd) const = 0;
	virtual FX_INT32				GetKeyAlgorithm(CFX_ByteString &bsAlgorithm) const = 0;
	virtual FX_INT32				GetKeyData(CFDRM_ByteKeyString &bksKey) const = 0;
	virtual FX_INT32				GetKeyHashType(CFX_ByteString &bsHashType) const = 0;
	virtual FX_INT32				GetKeyHashValue(CFX_ByteString &bsHashValue) const = 0;
	virtual IFDRM_CategoryRead*		GetSubjectParams() const = 0;
};

IFDRM_CertificateRead*		FDRM_CertificateRead_Create(IFDRM_DescRead *pDescRead = NULL);

class IFDRM_CertificateWrite : public IFDRM_CertificateRead
{
public:
	virtual IFDRM_DescWrite*		GetDescWrite() const = 0;
	virtual FX_INT32				InitCertificate(const CFDRM_DescData &descData, const CFDRM_ScriptData &scriptData) = 0;

 	virtual FX_INT32				SetVersion(FX_BSTR bsVersion) = 0;
	virtual FX_INT32				SetSerialNumber(FX_BSTR bsSN) = 0;
	virtual FX_INT32				SetEnvironmentInfo(FX_BSTR bsInfo) = 0;
	virtual FX_INT32				SetEnvironmentHashType(FX_BSTR bsHashType) = 0;
	virtual FX_INT32				SetEnvironmentHashValue(FX_BSTR bsHashValue) = 0;
	virtual IFDRM_CategoryWrite*	SetCertificateParams() = 0;

	virtual FX_INT32				SetIssuerID(FX_BSTR bsID) = 0;
	virtual FX_INT32				SetIssuerSerialNumber(FX_BSTR bsSN) = 0;
	virtual FX_INT32				SetIssuerServiceURL(FX_BSTR bsURL) = 0;
	virtual IFDRM_CategoryWrite*	SetIssuerParams() = 0;
	virtual FX_INT32				SetMasterID(FX_BSTR bsID) = 0;
	virtual FX_INT32				SetMasterSerialNumber(FX_BSTR bsSN) = 0;
	virtual FX_INT32				SetMasterServiceURL(FX_BSTR bsURL) = 0;
	virtual IFDRM_CategoryWrite*	SetMasterParams() = 0;

	virtual FX_INT32				SetSubjectID(FX_BSTR bsID) = 0;
	virtual FX_INT32				SetValidity(FX_BSTR bsStart, FX_BSTR bsEnd) = 0;
	virtual FX_INT32				SetKeyAlgorithm(FX_BSTR bsAlgorithm) = 0;
	virtual FX_INT32				SetKeyData(const CFDRM_ByteKeyString &bksKey) = 0;
	virtual FX_INT32				SetKeyHashType(FX_BSTR bsHashType) = 0;
	virtual FX_INT32				SetKeyHashValue(FX_BSTR bsHashValue) = 0;
	virtual IFDRM_CategoryWrite*	SetSubjectParams() = 0;
};

IFDRM_CertificateWrite*		FDRM_CertificateWrite_Create(IFDRM_DescWrite *pDescWrite = NULL);

/*@}*/

//*****************************************************************************
//* Envelope
//*****************************************************************************
class CFDRM_EnvelopeRead : public CFDRM_Object
{
public:
	virtual void		Release();

			FX_BOOL		LoadEnvelope(IFX_FileRead *pFile);
			FX_BOOL		ValidateEnvelope();

			//base info
			FX_BOOL		GetFormat(CFX_WideString &wsOrg, CFX_WideString &wsVer) const;
			FX_BOOL		GetApplication(CFX_WideString &wsOrg, CFX_WideString &wsVer) const;
			FX_BOOL		GetEnvelopeSN(CFX_WideString &wsSN) const;
			FX_BOOL		GetFileID(CFX_WideString &wsFileId) const;
			FX_BOOL		GetIssuer(CFX_WideString &wsIssuerId, CFX_WideString &wsIssuerCertSN, CFX_WideString &wsIssuerServiceURL) const;

			//permission info
			FX_BOOL 	GetConsumerId(CFX_WideString &wsConsumerId) const; 
			FX_INT32	CountAuthKeys() const;
			FX_BOOL		GetAuthKey(FX_INT32 nIndex, CFX_WideString &wsKeyId, CFX_WideString &wsTreatment, CFX_WideString &wsAuthValue) const;
			FX_INT32	CountLimits() const;
			FX_BOOL 	GetLimit(FX_INT32 nIndex, CFX_WideString &wsType, CFX_WideString &wsValue) const;
			FX_INT32	CountRights() const;
			FX_BOOL 	GetRight(FX_INT32 nIndex, CFX_WideString &wsRightType) const;

			//encryption info
			FX_BOOL		GetCipher(CFX_WideString &wsAlgorithm, CFX_WideString &wsEncryptKey) const;

protected:
	CFDRM_EnvelopeRead() : CFDRM_Object() {}
	virtual ~CFDRM_EnvelopeRead() {}
};

CFDRM_EnvelopeRead*		FDRM_EnvelopeRead_Create();

class CFDRM_EnvelopeWrite : public CFDRM_EnvelopeRead
{
public:
	void		CreateEnvelope();
	FX_BOOL		SaveEnvelope(IFX_FileWrite *pFile);

	//base info
	FX_BOOL		SetFormat(FX_WSTR wsOrg, FX_WSTR wsVer);
	FX_BOOL		SetApplication(FX_WSTR wsOrg, FX_WSTR wsVer);
	FX_BOOL		SetEnvelopeSN(FX_WSTR wsSN);
	FX_BOOL		SetFileID(FX_WSTR wsFileId);
	FX_BOOL		SetIssuer(FX_WSTR wsIssuerId, FX_WSTR wsIssuerCertSN, FX_WSTR wsIssuerServiceURL);

	//permission info
	FX_BOOL 	SetConsumerId(FX_WSTR wsConsumerId); 
	FX_BOOL		SetAuthKey(FX_WSTR wsKeyId, FX_WSTR wsTreatment, FX_WSTR wsAuthValue);
	FX_BOOL 	SetLimit(FX_WSTR wsType, FX_WSTR wsValue);
	FX_BOOL 	SetRight(FX_WSTR wsRightType);

	//encryption info
	FX_BOOL		SetCipher(FX_WSTR wsAlgorithm, FX_WSTR wsEncryptKey);

protected:
	CFDRM_EnvelopeWrite() : CFDRM_EnvelopeRead() {}
	virtual ~CFDRM_EnvelopeWrite() {}
};

CFDRM_EnvelopeWrite*	FDRM_EnvelopeWrite_Create();

#endif //_FDRM_PKI

/** @} */
